2018_lewitt_wall_drawing.py

#

SPDX-FileCopyrightText: 2018 Marion Vancoppenolle & Natalia Casas SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be

SPDX-License-Identifier: GPL-3.0-or-later

#

Sol Lewitt project Casas Natalia et Vancoppenolle Marion

import bpy
import random
import math
#

Supprimer de manière récurrente

from bpy import data as D
#
def delete_all():
    for item in D.objects:
        D.objects.remove(item)
    for item in D.meshes:
        D.meshes.remove(item)


delete_all()
#

1ére partie

Eléments

#
def lshape(_position, _type, _nom):
#

création du cube de base

    bpy.ops.mesh.primitive_cube_add(radius=0.5, location=_position)
    bpy.context.object.name = _nom

    cube = bpy.data.objects[_nom]
#

Biseau sur les coins de la forme

    bevelMod = cube.modifiers.new("MyBevel", "BEVEL")
    bevelMod.width = 0.05
#

Création du cube qui servira pour Boolean différence

    bpy.ops.mesh.primitive_cube_add(
        radius=0.5,
        location=(_position[0] + 0.2, _position[1] + 0.2, _position[2] + 0.2),
    )
    bpy.context.object.name = "CubeToDelete"

    cubeToDelete = bpy.data.objects["CubeToDelete"]

    bpy.context.scene.objects.active = cube
#

Boolean Difference

    extrudeCube = cube.modifiers.new("MyExtrudeCube", "BOOLEAN")
    extrudeCube.operation = "DIFFERENCE"
    extrudeCube.object = cubeToDelete
    bpy.ops.object.modifier_apply(apply_as="DATA", modifier="MyExtrudeCube")

    bpy.context.scene.objects.active = cubeToDelete
    bpy.ops.object.delete(use_global=False)
#

rotation de l’élement de base afin de créer 8 élément différents

    if _type == 0:
        _rotation = (0, 0, 0)
    if _type == 1:
        _rotation = (math.pi / 2, 0, 0)
    if _type == 2:
        _rotation = (0, math.pi / 2, 0)
    if _type == 3:
        _rotation = (0, 0, math.pi)
    if _type == 4:
        _rotation = (math.pi / 2, math.pi, -math.pi / 2)
    if _type == 5:
        _rotation = (0, math.pi, math.pi / 2)
    if _type == 6:
        _rotation = (math.pi / 2, math.pi, 0)
    if _type == 7:
        _rotation = (math.pi / 2, math.pi, math.pi / 2)

    cube.rotation_euler = _rotation
#

2ème partie

Création de l’objet principal

#

création d’une fonction qui permettra de supprimer un élément dans une liste donnée

def getNextDel(val, order, dimension, list):
    if val == -1:
        val = random.randint(
            0, len(list) - 1
        )  # Variante de suppression:permet que ce ne soit pas toujours les mêmes qui restent
    else:
        if order == 0:
            if val >= len(list):
                val = 0
        else:
            val = val - 1
            if val < 0:
                val = len(list) - 1
    return val
#

créer l’objet principal

def building(
    dimension,
):  # dimension : base cubique de dimension 2x2 (éléments) ou 3x3 ou 4x4 ou plus
    l = []
#

Point de départ : introduire un ordre de suppression, (un voisin doit toujours etre supprimé) possible autant avec une base cubique de 2x2 que 3x3

    if dimension % 2 == 0:
        x = dimension / 2 - 1
        y = dimension / 2 - 1
    else:
        x = (dimension - 1) / 2
        y = (
            dimension - 1
        ) / 2  # On a 2 possibilité de sens : les nombres paires et les impaires

    for i in range(0, dimension * dimension):
        l.append((x - ((dimension - 1) / 2), y - ((dimension - 1) / 2)))
        print("(" + str(x) + "," + str(y) + ")")

        if dimension % 2 == 0:  # nombres paires
            if x == y and x > dimension / 2 - 1:
                xNew = -1
                yNew = 0
            elif x == y and x <= dimension / 2 - 1:
                xNew = +1
                yNew = 0
            elif x > dimension / 2 - 1 and (x + y) == dimension - 1:
                xNew = 0
                yNew = +1
            elif x < dimension / 2 - 1 and x + y == dimension - 2:
                xNew = 0
                yNew = -1
#

4 éléments max par couche: 4 possibilités disposition des 4éléments par rapport au socle cubique

        else:  # nombres impaires
            if x == y and x > (dimension - 1) / 2:
                xNew = -1
                yNew = 0
            elif x == y and x <= (dimension - 1) / 2:
                xNew = +1
                yNew = 0
            elif x > (dimension - 1) / 2 and (x + y) == dimension:
                xNew = 0
                yNew = +1
            elif x < ((dimension - 1) / 2) and x + y == dimension - 1:
                xNew = 0
                yNew = -1
#

4 éléments max par couche: 4 possibilités disposition des 4éléments par rapport au socle cubique

        x = x + xNew
        y = y + yNew  # position par rapport au socle

    l1 = l[:]  # listes de chaque direction
    l2 = l[:]
    l3 = l[:]
    l4 = l[:]
    l5 = l[:]
    l6 = l[:]

    print(l)
#

socle cubique central

    for couche in range(0, dimension):

        i = 0
        for coord in l:
            lshape(
                (*coord, -((dimension - 1) / 2) + couche),
                random.randint(0, 7),
                "socle_" + str(couche) + "_" + str(i),
            )
            i = i + 1
#

AXE X

#

Un des deux cotés sur l’axe des x peut être diminué-tronqué

    SensTronque = random.randint(0, 1)

    if SensTronque == 0:
        nbcouches1 = random.randint(0, dimension * dimension - 1)
        nbcouches2 = dimension * dimension - 1
    else:
        nbcouches1 = dimension * dimension - 1
        nbcouches2 = random.randint(
            0, dimension * dimension - 1
        )  # si l'un des 2 est 'coupé', l' autre va automatiuement jusu'au bout
#

axe x gauche

    OrderDel = random.randint(
        0, 1
    )  # suppression d'un élément au hasard au fur et à mesure des couches
    NextDel = -1

    for couche in range(0, nbcouches1):

        NextDel = getNextDel(
            NextDel, OrderDel, dimension, l1
        )  # ordre de suppression: on garde une progression
#

l1: fait référence au sens créé plus tot

        del l1[NextDel]  # suppression définitive
        i = 0

        for coord in l1:
            lshape(
                (-couche - ((dimension + 1) / 2), coord[0], coord[1]),
                random.randint(0, 7),
                "XGauche_" + str(couche) + "_" + str(i),
            )
            i = (
                i + 1
            )  # la branche de l'axe x qui tire vers la gauche est disposée contre le socle cubique et chaque élément est disposé au hasard
#

axe x droite

    OrderDel = random.randint(
        0, 1
    )  # suppression d'un élément au hasard au fur et à mesure des couches
    NextDel = -1

    for couche in range(0, nbcouches2):
        NextDel = getNextDel(
            NextDel, OrderDel, dimension, l2
        )  # ordre de suppression: on garde une progression
        del l2[
            NextDel
        ]  # suppression définitive                    # l2: fait référence au sens créé plus tot
        i = 0

        for coord in l2:
            lshape(
                (couche + ((dimension + 1) / 2), coord[0], coord[1]),
                random.randint(0, 7),
                "XDroite_" + str(couche) + "_" + str(i),
            )
            i = (
                i + 1
            )  # la branche de l'axe x qui tire vers la droite est disposée contre le socle cubique et chaque élément est disposé au hasard
#

AXE Y

#

Un des deux cotés sur l’axe des x peut être diminué-tronqué

    if SensTronque == 0:
        nbcouches1 = random.randint(0, dimension * dimension - 1)
        nbcouches2 = dimension * dimension - 1
    else:
        nbcouches1 = dimension * dimension - 1
        nbcouches2 = random.randint(
            0, dimension * dimension - 1
        )  # si l'un des 2 est 'coupé', l' autre va automatiuement jusu'au bout
#

axe y arrière

    OrderDel = random.randint(
        0, 1
    )  # suppression d'un élément au hasard au fur et à mesure des couches
    NextDel = -1

    for couche in range(0, nbcouches1):
        NextDel = getNextDel(
            NextDel, OrderDel, dimension, l3
        )  # ordre de suppression: on garde une progression
        del l3[NextDel]
        i = 0

        for coord in l3:
            lshape(
                (coord[1], -couche - ((dimension + 1) / 2), coord[0]),
                random.randint(0, 7),
                "YArriere_" + str(couche) + "_" + str(i),
            )
            i = i + 1
#

axe y avant

    OrderDel = random.randint(
        0, 1
    )  # suppression d'un élément au hasard au fur et à mesure des couches
    NextDel = -1
    for couche in range(0, nbcouches2):
        NextDel = getNextDel(
            NextDel, OrderDel, dimension, l4
        )  # ordre de suppression: on garde une progression
        i = 0

        for coord in l4:
            lshape(
                (coord[0], couche + ((dimension + 1) / 2), coord[1]),
                random.randint(0, 7),
                "YAvant_" + str(couche) + "_" + str(i),
            )
            i = i + 1
#

AXE Z

#

Un des deux cotés sur l’axe des x peut être diminué-tronqué

    if SensTronque == 0:
        nbcouches1 = random.randint(0, dimension * dimension - 1)
        nbcouches2 = dimension * dimension - 1
    else:
        nbcouches1 = dimension * dimension - 1
        nbcouches2 = random.randint(
            0, dimension * dimension - 1
        )  # si l'un des 2 est 'coupé', l' autre va automatiuement jusqu'au bout (jusqu'à la couche où il ne reste qu'un seul élément)
#

axe z haut

    OrderDel = random.randint(
        0, 1
    )  # suppression d'un élément au hasard au fur et à mesure des couches
    NextDel = -1

    for couche in range(0, nbcouches1):
        NextDel = getNextDel(
            NextDel, OrderDel, dimension, l5
        )  # ordre de suppression: on garde une progression
        del l5[NextDel]
        i = 0

        for coord in l5:
            lshape(
                (coord[0], coord[1], couche + ((dimension + 1) / 2)),
                random.randint(0, 7),
                "ZHaut_" + str(couche) + "_" + str(i),
            )
            i = (
                i + 1
            )  # la branche de l'axe de z qui tire vers le haut est disposé contre le socle cubique et chaque élément est disposé au hasard
#

axe z Bas

    OrderDel = random.randint(
        0, 1
    )  # suppression d'un élément au hasard au fur et à mesure des couches
    NextDel = -1

    for couche in range(0, nbcouches2):
        NextDel = getNextDel(
            NextDel, OrderDel, dimension, l6
        )  # ordre de suppression: on garde une progression
        del l6[NextDel]
        i = 0

        for coord in l6:
            lshape(
                (coord[0], coord[1], -couche - ((dimension + 1) / 2)),
                random.randint(0, 7),
                "ZBas_" + str(couche) + "_" + str(i),
            )
            i = i + 1


building(2)  # dimension : base cubique de 2x2 ou 3x3 ou 4x4 ou plus